package com.gm.commonlib.util.numberUtils;

import java.math.BigDecimal;
import java.util.regex.Pattern;

public class DigitUtil {
    public final static int BIT_0 = 0;
    public final static int BIT_1 = 1;
    public final static int BIT_2 = 2;
    public final static int BIT_3 = 3;

    public final static Pattern DecimalPattern = Pattern.compile("^[+-]?((\\d+\\.\\d*)|(\\d*\\.\\d+)|(\\d+))$");

    private final static BigDecimal MAX_LONG = new BigDecimal(Long.MAX_VALUE);
    private final static BigDecimal MAX_FLOAT = new BigDecimal(Float.MAX_VALUE);
    private final static BigDecimal MAX_INT = new BigDecimal(Integer.MAX_VALUE);
    private final static BigDecimal MAX_DOUBLE = new BigDecimal(Double.MAX_VALUE);

    //--------------------------------------int-------------------------------------------------
    public static Integer orgParseInteger(String value) {
        return orgParseInteger(value, null);
    }
    public static Integer orgParseInteger(String value, Integer defValue) {
        if(value == null || "".equals(value.trim())) {
            return defValue;
        }
        try {
            return Integer.valueOf(value);
        } catch (Throwable throwable) {
            return defValue;
        }
    }
    //TODO CORE
    public static int parseInt(String value) {
        int result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_INT);
            if (maxJuge > 0) {
                result = Integer.MAX_VALUE;
            } else {
                result = bigDecimal.intValue();
            }
        } else {
            result = 0;
        }
        return result;
    }
    //TODO CORE
    public static int parseIntUp(String value) {
        int result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_INT);
            if (maxJuge > 0) {
                result = Integer.MAX_VALUE;
            } else {
                result = bigDecimal.setScale(BIT_0, BigDecimal.ROUND_HALF_UP).intValue();
            }
        } else {
            result = 0;
        }
        return result;
    }
    //TODO CORE
    public static String parseIntString(int value) {
        return new BigDecimal(value).toString();
    }

    public static String parseIntString(double value) {
        return NumberUtils.subZeroAndDot(parseIntString((int)value));
    }

    //--------------------------------------long-------------------------------------------------
    public static Long orgParseLong(String value) {
        return orgParseLong(value, null);
    }

    public static Long orgParseLong(String value, Long defValue) {
        if(value == null || "".equals(value.trim())) {
            return defValue;
        }
        try {
            return Long.valueOf(value);
        } catch (Throwable throwable) {
            return defValue;
        }
    }
    //TODO CORE
    public static long parseLong(String value) {
        long result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_LONG);
            if (maxJuge > 0) {
                result = Long.MAX_VALUE;
            } else {
                result = bigDecimal.longValue();
            }
        } else {
            result = 0L;
        }
        return result;
    }
    //TODO CORE
    public static long parseLongUp(String value) {
        long result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_LONG);
            if (maxJuge > 0) {
                result = Long.MAX_VALUE;
            } else {
                result = bigDecimal.setScale(BIT_0, BigDecimal.ROUND_HALF_UP).longValue();
            }
        } else {
            result = 0L;
        }
        return result;
    }
    //TODO CORE
    public static String parseLongString(long value) {
        return new BigDecimal(value).toString();
    }

    //--------------------------------------float-------------------------------------------------
    public static float orgParseFloat(String value) {
        if(value == null || "".equals(value.trim())) {
            return 0;
        }
        try {
            return Float.parseFloat(value);
        } catch (Throwable throwable) {
            return 0;
        }
    }

    public static float parseFloat(String value) {
        return parseFloat(value, BIT_2);
    }

    public static float parseFloat(float value) {
        return parseFloat(value, BIT_2);
    }

    public static float parseFloat(Float value) {
        return parseFloat(value, BIT_2);
    }

    public static String parseFloatString(Float value) {
        return parseFloatString(value, BIT_2);
    }

    public static String parseFloatString(float value) {
        return parseFloatString(value, BIT_2);
    }

    public static float parseFloat(Float value, int bit) {
        if(value != null) {
            return parseFloat(value.floatValue(), bit);
        } else {
            return 0.00f;
        }
    }

    public static String parseFloatString(Float value, int bit) {
        if(value != null) {
            return parseFloatStringImpl(value, bit);
        } else {
            return parseFloatStringImpl(0, bit);
        }
    }

    public static String parseFloatString(float value, int bit) {
        return parseFloatStringImpl(value, bit);
    }
    //TODO CORE
    public static float parseFloat(String value, int bit) {
        float result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_FLOAT);
            if (maxJuge > 0) {
                result = Float.MAX_VALUE;
            } else {
                result = bigDecimal.setScale(bit, BigDecimal.ROUND_HALF_UP).floatValue();
            }
        } else {
            result = 0;
        }
        return result;
    }
    //TODO CORE
    public static float parseFloat(float value, int bit) {
        return new BigDecimal(value).setScale(bit, BigDecimal.ROUND_HALF_UP).floatValue();
    }
    //TODO CORE
    private static String parseFloatStringImpl(float value, int bit) {
        return new BigDecimal(value).setScale(bit, BigDecimal.ROUND_HALF_UP).toString();
    }

    //--------------------------------------double-------------------------------------------------
    public static double orgParseDouble(String value) {
        if(value == null || "".equals(value.trim())) {
            return 0;
        }
        try {
            return Double.parseDouble(value);
        } catch (Throwable throwable) {
            return 0;
        }
    }
    public static double orgParseDouble(Double value) {
        if(value == null) {
            return 0;
        }
        try {
            return value;
        } catch (Throwable throwable) {
            return 0;
        }
    }

    public static double parseDouble(String value) {
        return parseDouble(value, BIT_2);
    }

    public static double parseDouble(double value) {
        return parseDouble(value, BIT_2);
    }

    public static double parseDouble(Double value) {
        return parseDouble(value, BIT_2);
    }

    public static String parseFloatString(Double value) {
        return parseDoubleString(value, BIT_2);
    }

    public static String parseDoubleString(double value) {
        return parseDoubleString(value, BIT_2);
    }

    public static String parseDoubleStringWithTrunk(double value) {
        return parseDoubleStringWithTrunk(value, BIT_2);
    }

    public static float parseDouble(Double value, int bit) {
        if(value != null) {
            return new BigDecimal(value).setScale(bit, BigDecimal.ROUND_HALF_UP).floatValue();
        } else {
            return 0.00f;
        }
    }

    public static String parseDoubleString(Double value, int bit) {
        if(value != null) {
            return parseDoubleStringImpl(value, bit);
        } else {
            return parseDoubleStringImpl(0, bit);
        }
    }

    public static String parseDoubleStringWithTrunk(double value, int bit) {
        return parseDoubleString(value, bit);
    }

    public static String parseDoubleStringWithTrunk(String value, int bit) {
        double result = parseDoubleImpl(value, bit);
        return parseDoubleString(result, bit);
    }

    public static String parseDoubleStringWithTrunk(String result) {
        if(result == null) {
            return result;
        }
        if(result.endsWith(".000")) {
            result = result.replaceAll("\\.000", "");
        } else if(result.endsWith(".00")) {
            result = result.replaceAll("\\.00", "");
        } else if(result.endsWith(".0")) {
            result = result.replaceAll("\\.0", "");
        } else if(result.endsWith(".")) {
            result = result.replaceAll("\\.", "");
        } else if("0".equals(result)) {
            result = "";
        } else {
            //TODO
            result = result;
        }
        return result;
    }

    public static String parseDoubleString(double value, int bit) {
        return NumberUtils.subZeroAndDot(parseDoubleStringImpl(value, bit));
    }
    //TODO CORE
    public static double parseDouble(String value, int bit) {
        double result = 0;
        if(value == null) {
            return result;
        }
        if (DecimalPattern.matcher(value).matches()) {
            BigDecimal bigDecimal = new BigDecimal(value);
            int maxJuge = bigDecimal.compareTo(MAX_DOUBLE);
            if (maxJuge > 0) {
                result = Double.MAX_VALUE;
            } else {
                result = bigDecimal.setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
        } else {
            try {
                result = Double.parseDouble(value);
            } catch (Throwable e) {
                result = 0;
            }
        }
        return result;
    }
    //TODO CORE
    public static double parseDouble(double value, int bit) {
        BigDecimal bd= new BigDecimal(new Double(value).toString());
        return bd.setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    //TODO CORE
    public static String parseDoubleStringImpl(double value, int bit) {
        return new BigDecimal(new Double(value).toString()).setScale(bit, BigDecimal.ROUND_HALF_UP).toString();
    }

    //TODO CORE
    public static double parseDoubleImpl(String value, int bit) {
        return new BigDecimal(value).setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    //TODO CORE
    public static double parseDoubleImpl(double value, int bit) {
        return new BigDecimal(Double.toString(value)).setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double halfUp(BigDecimal bigDecimal, int bit) {
        if (bigDecimal != null) {
            return bigDecimal.setScale(bit, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        return 0;
    }
}
